namespace Asmex.FileViewer
{
    using System;
    using System.IO;

    public class ModHeaders
    {
        private Asmex.FileViewer.COR20Header _cor20;
        private Asmex.FileViewer.OSHeaders _hdr;
        private Asmex.FileViewer.MetaDataHeaders _md;
        private Asmex.FileViewer.MetaDataTableHeader _mdth;

        public ModHeaders(BinaryReader reader)
        {
            this._hdr = new Asmex.FileViewer.OSHeaders(reader);
            try
            {
                reader.BaseStream.Position = this.Rva2Offset(this._hdr.PEHeader.DataDirs[14].Rva);
                this._cor20 = new Asmex.FileViewer.COR20Header(reader);
            }
            catch (Exception)
            {
                return;
            }
            try
            {
                reader.BaseStream.Position = this.Rva2Offset(this._cor20.MetaData.Rva);
                this._md = new Asmex.FileViewer.MetaDataHeaders(reader);
            }
            catch (Exception)
            {
                return;
            }
            try
            {
                reader.BaseStream.Position = this._md.TableStreamHeader.Offset + this._md.StorageSigAndHeader.Start;
                this._mdth = new Asmex.FileViewer.MetaDataTableHeader(reader);
            }
            catch (Exception)
            {
            }
        }

        public uint Rva2Offset(uint rva)
        {
            for (int i = 0; i < this._hdr.SectionHeaders.Length; i++)
            {
                SectionHeader header = this._hdr.SectionHeaders[i];
                if ((header.VirtualAddress <= rva) && ((header.VirtualAddress + header.SizeOfRawData) > rva))
                {
                    return (header.PointerToRawData + (rva - header.VirtualAddress));
                }
            }
            throw new ModException("Module:  Invalid RVA address.");
        }

        public Asmex.FileViewer.COR20Header COR20Header
        {
            get
            {
                return this._cor20;
            }
        }

        public Asmex.FileViewer.MetaDataHeaders MetaDataHeaders
        {
            get
            {
                return this._md;
            }
        }

        public Asmex.FileViewer.MetaDataTableHeader MetaDataTableHeader
        {
            get
            {
                return this._mdth;
            }
        }

        public Asmex.FileViewer.OSHeaders OSHeaders
        {
            get
            {
                return this._hdr;
            }
        }
    }
}
